import React, { useEffect, useImperativeHandle, useRef, useState, forwardRef } from 'react';
import './Earth3D.css';
import { GlbRenderer, GlbRendererOptions } from './GlbRenderer';
import { LatLngPoint, LatLngRect, LocationPoint, DetectionPoint } from '../types/earth';

interface EarthGlbProps {
  modelUrl: string;
  radius: number;
  rects?: LatLngRect[];
  locationPoints?: LocationPoint[];
  detectionPoints?: DetectionPoint[];
  onHover?: (coord: LatLngPoint | null) => void;
  onClick?: (coord: LatLngPoint | null) => void;
  onLocationHover?: (location: LocationPoint | null) => void;
  onLocationClick?: (location: LocationPoint | null) => void;
  onDetectionPointHover?: (detectionPoint: DetectionPoint | null) => void;
  onDetectionPointClick?: (detectionPoint: DetectionPoint | null) => void;
  onSelectionChange?: (selectionRect: LatLngRect | null) => void;
  onSelectionEnd?: (selectionRect: LatLngRect | null, intersectingRects: LatLngRect[], intersectingDetectionPoints: DetectionPoint[]) => void;
  externalSelection?: LatLngRect | null;
  simulatedMetaKey?: boolean;
}

export interface EarthGlbRef {
  zoomIn: () => void;
  zoomOut: () => void;
  resetView: () => void;
  getCameraZ: () => number;
  setCameraZ: (z: number) => void;
  enterSelectionMode: () => void;
  exitSelectionMode: () => void;
  clearSelection: () => void;
}

const EarthGlb = forwardRef<EarthGlbRef, EarthGlbProps>(({ 
  modelUrl,
  radius,
  rects = [],
  locationPoints = [],
  detectionPoints = [],
  onHover,
  onClick,
  onLocationHover,
  onLocationClick,
  onDetectionPointHover,
  onDetectionPointClick,
  onSelectionChange,
  onSelectionEnd,
  externalSelection,
  simulatedMetaKey = false
}, ref) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const rendererRef = useRef<GlbRenderer | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useImperativeHandle(ref, () => ({
    zoomIn: () => { rendererRef.current?.zoomIn(); },
    zoomOut: () => { rendererRef.current?.zoomOut(); },
    resetView: () => { rendererRef.current?.resetView(); },
    getCameraZ: () => { return rendererRef.current?.getCameraZ() || 0; },
    setCameraZ: (z: number) => { rendererRef.current?.setCameraZ(z); },
    enterSelectionMode: () => {},
    exitSelectionMode: () => { rendererRef.current?.clearSelection(); },
    clearSelection: () => { rendererRef.current?.clearSelection(); }
  }));

  useEffect(() => {
    if (!containerRef.current) { return; }
    setIsLoading(true);
    const options: GlbRendererOptions = {
      modelUrl,
      radius,
      rects,
      locationPoints,
      detectionPoints,
      onHover: (coord) => { onHover?.(coord); },
      onClick: (coord) => { onClick?.(coord); },
      onLocationHover: (location) => { onLocationHover?.(location); },
      onLocationClick: (location) => { onLocationClick?.(location); },
      onDetectionPointHover: (d) => { onDetectionPointHover?.(d); },
      onDetectionPointClick: (d) => { onDetectionPointClick?.(d); },
      onSelectionChange: (rect) => { onSelectionChange?.(rect); },
      onSelectionEnd: (rect, rects, points) => { onSelectionEnd?.(rect, rects, points); setIsLoading(false); },
      simulatedMetaKey
    };
    try {
      rendererRef.current = new GlbRenderer(containerRef.current, options);
      setIsLoading(false);
    } catch (e: any) {
      setError(e?.message || 'GLB 初始化失败');
      setIsLoading(false);
    }
    return () => {
      rendererRef.current?.dispose();
      rendererRef.current = null;
    };
  }, [modelUrl, radius]);

  useEffect(() => {
    rendererRef.current?.setRects(rects);
  }, [rects]);

  useEffect(() => {
    rendererRef.current?.setLocationPoints(locationPoints);
  }, [locationPoints]);

  useEffect(() => {
    rendererRef.current?.setDetectionPoints(detectionPoints);
  }, [detectionPoints]);

  useEffect(() => {
    rendererRef.current?.setExternalSelection(externalSelection || null);
  }, [externalSelection]);

  useEffect(() => {
    rendererRef.current?.setSimulatedMetaKey(simulatedMetaKey);
  }, [simulatedMetaKey]);

  return (
    <div className="earth-3d-container" style={{ width: '100%', height: '100%' }}>
      <div 
        ref={containerRef}
        className="earth-3d-canvas"
        style={{ 
          width: '100%', 
          height: '100%',
          position: 'relative',
          cursor: simulatedMetaKey ? 'crosshair' : 'grab',
          minHeight: '400px'
        }}
      />
      {isLoading && (
        <div className="loading-overlay">
          <div className="loading-spinner">
            <div className="spinner"></div>
            <div className="loading-text">正在加载3D模型...</div>
          </div>
        </div>
      )}
      {error && (
        <div className="error-overlay">
          <div className="error-message">
            <div className="error-icon">⚠️</div>
            <div className="error-text">{error}</div>
            <button 
              className="retry-button"
              onClick={() => window.location.reload()}
            >
              重试
            </button>
          </div>
        </div>
      )}
    </div>
  );
});

EarthGlb.displayName = 'EarthGlb';

export default EarthGlb;


